package com.michael.demos.base.thread.juc;

import java.util.Random;
import java.util.concurrent.*;

/**
 * 类功能描述:
 * <pre>
 * 		回环栅栏 使用 DEMO AQS实现
 * </pre>
 *
 * @author Michael
 * @version 1.0
 * @date 2020/8/12 14:24
 */
public class CyclicBarrierDemo {

	public static void main(String[] args) {
		doRunning();
	}

	/** 模拟跑步比赛 */
	public static void doRunning() {

		CyclicBarrier barrier = new CyclicBarrier(5, new Runnable() {
			@Override
			public void run() {
				System.out.println("裁判:各就位...预备...跑！");
			}
		});

		System.out.println("现在进行一百米比赛");

		// 初始化一个线程池
		ExecutorService es = Executors.newFixedThreadPool(5);

		es.submit(new Runner(barrier, "张三"));
		es.submit(new Runner(barrier, "李四"));
		es.submit(new Runner(barrier, "王五"));
		es.submit(new Runner(barrier, "赵六"));
		es.submit(new Runner(barrier, "田七"));

		es.shutdown();
	}
}

/** 跑步运动员 */
class Runner extends Thread {
	private CyclicBarrier barrier;
	private String name;

	public Runner(CyclicBarrier barrier, String name) {
		this.barrier = barrier;
		this.name = name;
	}

	private int getRandomInt(int min, int max) {
		Random random = new Random();
		return min + random.nextInt((max - min) + 1);
	}

	@Override
	public void run() {

		try {
			int randomInt = getRandomInt(1000, 2000);
			TimeUnit.MILLISECONDS.sleep(randomInt);
			System.out.println(name + ":准备完毕");
			// 等待所有人准备好
			barrier.await();
		} catch (InterruptedException | BrokenBarrierException e) {
			e.printStackTrace();
		} finally {
			System.out.println(name + "起跑了...");
			try {
				TimeUnit.MILLISECONDS.sleep(getRandomInt(5000, 8000));
			} catch (InterruptedException e) {
				e.printStackTrace();
			} finally {
				System.out.println(name + "到达终点");
			}
		}
	}
}